/**
 * Created by oneminute on 2014/4/26.
 */

var async = require("async");
var lz = require("../utils/modules")();
var moment = require("moment");

function User(_opts) {
    lz.Persistent.call(this, _opts);
    if (!_opts) _opts = {};
    if (!_opts.email) {
        _opts.email = {
            uid: _opts.id
        };
    } else {
        _opts.email.uid = _opts.email.uid || _opts.id || "";
    }
    this.__properties.pushArray([
        { name: "id", value: _opts.id || "" },
        { name: "name", value: _opts.name || "" },
        { name: "email", value: /*Array.isArray(_opts.email) ? new lz.Email(_opts.email[0]) :*/ new lz.Email(_opts.email) || null },
        { name: "password", value: _opts.password || "" },
        { name: "address", value: _opts.address || "" },
        { name: "lon", value: _opts.lon || 0 },
        { name: "lat", value: _opts.lat || 0 },
        { name: "distance", value: _opts.distance || 0 },
        { name: "phone", value: _opts.phone || "" },
        { name: "loginPhone", value: _opts.loginPhone || "" },
        { name: "description", value: _opts.description || "" },
        { name: "photo", value: _opts.photo || null },
        { name: "inbusiness", value: _opts.inbusiness || false },
        { name: "userpoint", value: 0 },
        { name: "level", value: 0 },
        { name: "state", value: 0 },
        { name: "limit", value: _opts.limit || 3 },
        { name: "commodities", value: (function () {
            if (!_opts.commodities) return [];
            var items = [];
            _opts.commodities.forEach(function (_commodity) {
                items.push(new lz.Commodity(_commodity));
            });
            return items;
        })()},
        { name: "accounts", value: (function () {
            if (!_opts.accounts) return [];
            var items = [];
            _opts.accounts.forEach(function (_account) {
                items.push(new lz.Account(_account));
            });
            return items;
        })() },
        { name: "demands", value: (function () {
            if (!_opts.demands) return [];
            var items = [];
            _opts.demands.forEach(function (_demand) {
                items.push(new lz.Demand(_demand));
            });
            return items;
        })() },
        { name: "gifts", value: (function () {
            if (!_opts.gifts) return [];
            var items = [];
            _opts.gifts.forEach(function (_gift) {
                items.push(new lz.Gift(_gift));
            });
            return items;
        })() },
        { name: "registerTime", value: _opts.registerTime || moment().format(lz.Config.datetimeFormat) },
        { name: "online", value: _opts.online || false }
    ]);
    this.__initProperties();
    this.__collection = lz.Config.db.arango.users;
    this.__aql = lz.Config.db.arango.aqls.GET_FULL_USER_BY_PROP;
}

require("util").inherits(User, lz.Persistent);

User.prototype.login = function (_callback) {
    lz.Logger.debug("user:login: 调用.");
    var self = this;
    var password = self.password;

    self.load({
        method: "byAQL",
        aql: lz.Config.db.arango.aqls.GET_OBJECT_BY_PROPERTY,
        params: {
            "@collection": lz.Config.db.arango.users,
            "prop": "loginPhone",
            "value": self.loginPhone
        },
        loadAll: false}, function (_err, _user) {
        if (_err) {
            lz.Logger.error("User:login: 登录时出现系统错误。", _err);
            _callback(_err);
            return;
        }

        if (!_user) {
            lz.Logger.error("User:login: 用户名不存在。");
            _callback(lz.Config.errors.getError(lz.Config.errors.LOGIN_USER_NOT_FOUND));
            return;
        }

        if (self.password == password) {
            if (_user.online) {
                lz.Logger.error("User:login: 用户已在另一处登陆。");
                //_callback(lz.Config.errors.getError(lz.Config.errors.LOGIN_ALREADY_ONLINE));
                //return;
            }
            _callback(null, self);
            //self.online = true;
            //self.save({saveAll: false}, function (_err, _user) {
            //    _callback(null, self);
            //});
        } else {
            _callback(lz.Config.errors.getError(lz.Config.errors.LOGIN_WRONG_PASSWORD));
        }
    });
};

/**
 *
 * @param _callback
 */
User.prototype.register = function (_callback) {
    lz.Logger.debug("User:register: 调用。", this.email.email);
    var self = this;
    self.id = lz.Utils.getUUID("u_");
    self.name = lz.Utils.getRandName();
    self.email.uid = self.id;

    // 判断用户是否已存在。
    function checkAndCreateName(_cb) {
        lz.ArangoDB.countObjectsByAQL(lz.Config.db.arango.aqls.GET_USER_BY_NAME, {
            "@collection": self.__collection,
            "name": self.name
        }, function (_err, _count) {
            if (_err) {
                _callback(lz.Config.errors.getError(lz.Config.errors.ARANGODB_SYSTEM_ERROR));
                return;
            }

            if (_count > 0) {
                self.name = lz.Utils.getRandName();
                checkAndCreateName(_cb);
            } else {
                _cb(null);
            }
        });
    }

    checkAndCreateName(function () {
        lz.ArangoDB.countObjectsByAQL(lz.Config.db.arango.aqls.GET_OBJECT_BY_PROPERTY, {
            "@collection": lz.Config.db.arango.emails,
            "prop": "email",
            "value": self.email.email
        }, function (_err, _count) {
            if (_err) {
                _callback(lz.Config.errors.getError(lz.Config.errors.ARANGODB_SYSTEM_ERROR));
                return;
            }

            if (_count > 0) {
                _callback(lz.Config.errors.getError(lz.Config.errors.REGISTER_EMAIL_EXISTED));
                return;
            }

            self.save(function (_err, _user) {
                if (_err || !_user) {
                    _callback(lz.Config.errors.getError(lz.Config.errors.ARANGODB_SYSTEM_ERROR));
                    return;
                }

                _callback(null, self);
            });
        });
    });
};

User.prototype.topItem = function (_propName, _aid, _callback) {
    var self = this;
    var prop = self[_propName];
    var index = -1;
    prop.forEach(function (_item, _index) {
        if (_item._id == _aid) {
            index = _index;
        }
    });
    if (index >= 0) {
        var item = prop[index];
        prop.splice(index, 1);
        prop.unshift(item);
    } else {
        _callback(lz.Config.errors.getError(lz.Config.errors.REQUEST_DATA_NOT_BELANG_USER));
        return;
    }
    self.save({saveAll: false}, function (_err, _user) {
        _callback(_err, _user);
    });
};

User.prototype.getGoodsById = function (_gid) {
    logger.debug("user:getGoodsById: invoke.", this.sellingGoods.length, _gid);
    var retGoods = null;
    this.sellingGoods.forEach(function (_goods) {
        if (_gid == _goods.id) {
            logger.debug("user:getGoodsById: ", _goods.id, _gid);
            retGoods = _goods;
        }
    });
    return retGoods;
};

User.prototype.getNeedById = function (_nid) {
    logger.debug("user:getNeedById: invoke.", this.needs.length, _nid);
    var retNeed = null;
    this.needs.forEach(function (_need) {
        if (_nid == _need.id) {
            logger.debug('user:getNeedById: ', _need.id, _nid);
            retNeed = _need;
        }
    });
    return retNeed;
};

User.prototype.deleteCommodity = function (_cid, _callback) {
    lz.Logger.debug("User:deleteCommodity: 调用。");
    var self = this;
    var commodity = null;
    var index = -1;
    for (var i = 0; i < self.commodities.length; i++) {
        if (self.commodities[i].id == _cid) {
            commodity = self.commodities[i];
            index = i;
            break;
        }
    }

    if (commodity) {
        self.commodities.splice(index, 1);
        commodity.delete(function (_err) {
            if (_err) {
                lz.Logger.error("User:deleteCommodity: 删除商品出现错误。");
                _callback(lz.Config.errors.getError(lz.Config.errors.ARANGODB_SYSTEM_ERROR));
                return;
            }

            self.save({saveAll: false}, function (_err, _user) {
                if (_err) {
                    lz.Logger.error("User:deleteCommodity: ", _err);
                    _callback(_err);
                    return;
                }
                _callback(null, self);
            });
        });
    } else {
        _callback(lz.Config.errors.getError(lz.Config.errors.REQUEST_NO_COMMODITY));
    }
};

User.prototype.addNeed = function (_need) {
    logger.debug("User:addNeed: ", this.id, _need.id);
    this.needs.unshift(_need);
    this.updateNeedsOrder();
    logger.debug("User.addNeed: ", this.needs.length);
};

User.prototype.deleteDemand = function (_did, _callback) {
    lz.Logger.debug("User:deleteDemand: 调用。");
    var self = this;
    var demand = null;
    var index = -1;
    for (var i = 0; i < self.demands.length; i++) {
        if (self.demands[i].id == _did) {
            demand = self.demands[i];
            index = i;
            break;
        }
    }

    if (demand) {
        self.demands.splice(index, 1);
        demand.delete(function (_err) {
            if (_err) {
                lz.Logger.error("User:deleteDemand: 删除需求出现错误。");
                _callback(lz.Config.errors.getError(lz.Config.errors.ARANGODB_SYSTEM_ERROR));
                return;
            }

            self.save({saveAll: false}, function (_err, _user) {
                if (_err) {
                    lz.Logger.error("User:deleteDemand: ", _err);
                    _callback(_err);
                    return;
                }
                _callback(null, self);
            });
        });
    }
};

User.prototype.modifyName = function (_name, _callback) {
    var self = this;

    lz.ArangoDB.countObjectsByAQL(lz.Config.db.arango.aqls.GET_OBJECT_BY_PROPERTY, {
        "@collection": self.__collection,
        "prop": "name",
        "value": _name
    }, function (_err, _count) {
        if (_err) {
            _callback(lz.Config.errors.getError(lz.Config.errors.ARANGODB_SYSTEM_ERROR));
            return;
        }

        if (_count > 0) {
            _callback(lz.Config.errors.getError(lz.Config.errors.REGISTER_USER_EXISTED));
            return;
        }

        self.modifyProperty({
            fields: {
                name: _name
            },
            condition: {
                prop: '_id',
                value: self._id
            }
        }, function (_err) {
            _callback(_err, self);
        });
    });
};

User.prototype.getInfo = function (_imgPrefix) {
    var imgPrefix = _imgPrefix || 't';
    var obj = this.getFields(['id', 'name', 'address', 'lat', 'lon', 'phone', 'description', 'inbusiness', 'online', 'photo']);
    //obj.photo = lz.ImageManager.getPhoto(_imgPrefix);
    return obj;
};

User.prototype.getInfoWithCommodities = function (_imgPrefix, _commodityImgPrefix) {
    var imgPrefix = _imgPrefix || 't';
    var commodityImgPrefix = _commodityImgPrefix || 't';
    var obj = this.getFields(['id', 'name', 'address', 'lat', 'lon', 'phone', 'description', 'inbusiness', 'online', 'photo']);
    //obj.photo = lz.ImageManager.getPhoto(_imgPrefix);
    obj.goods = [];
    this.commodities.forEach(function (_commodity) {
        obj.goods.push(_commodity.getInfo(_commodityImgPrefix));
    });
    return obj;
};

User.prototype.getInfoWithDemands = function (_imgPrefix) {
    var imgPrefix = _imgPrefix || 't';
    var commodityImgPrefix = _demandImgPrefix || 't';
    var obj = this.getFields(['id', 'name', 'address', 'lat', 'lon', 'phone', 'description', 'inbusiness', 'online', 'photo']);
    //obj.photo = lz.ImageManager.getPhoto(imgPrefix);
    obj.needs = [];
    this.demands.forEach(function (_demand) {
        obj.needs.push(_demand.getInfo());
    });
    return obj;
};

User.prototype.setOnline = function (_online, _callback) {
    lz.Logger.debug("User:setOnline: 调用。");
    var self = this;
    self.modifyProperty({
        fields: {
            online: _online
        },
        condition: {
            prop: '_id',
            value: self._id
        }
    }, function (_err) {
        if (_err) {
            lz.Logger.error("User:setOnline: 设置在线状态失败。", _online, _err);
            _callback(_err);
            return;
        }
        lz.Logger.debug("User:setOnline: 设置在线状态成功。", _online);
        _callback(_err, self);
    });
};

User.prototype.modifyPassword = function (_oldPassword, _newPassword, _callback) {
    lz.Logger.debug("User:modifyPassword: 调用。");
    var self = this;
    if (self.password != _oldPassword) {
        lz.Logger.warn("User:modifyPassword: 原密码错误。");
        _callback(lz.Config.errors.getError(lz.Config.errors.LOGIN_WRONG_PASSWORD));
        return;
    }

    self.modifyProperty({
        fields: {
            password: _newPassword
        },
        condition: {
            prop: '_id',
            value: self._id
        }
    }, function (_err) {
        if (_err) {
            lz.Logger.error("User:modifyPassword: 修改密码错误失败。", _err);
            _callback(_err);
            return;
        }
        lz.Logger.debug("User:modifyPassword: 修改密码成功。");
        _callback(_err, self);
    });
};

exports = module.exports = User;